/**
 * 
 */
package com.bbva.kyfb.kyfbbofi;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import javax.persistence.PersistenceException;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.hibernate.exception.ConstraintViolationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.bbva.jee.arq.spring.core.contexto.ArqSpringContext;
import com.bbva.jee.arq.spring.core.gce.ExcepcionEjecucionAplicacion;
import com.bbva.jee.arq.spring.core.log.I18nLog;
import com.bbva.jee.arq.spring.core.log.I18nLogFactory;
import com.bbva.jee.arq.spring.core.util.excepciones.PropiedadNoEncontradaExcepcion;
import com.bbva.kyfb.kyfbdaofi.IFirmasDao;
import com.bbva.kyfb.kyfbdto.firmas.bo.ComponentePutFirma;
import com.bbva.kyfb.kyfbdto.firmas.bo.DatosPAU;
import com.bbva.kyfb.kyfbdto.firmas.bo.FicheroInfo;
import com.bbva.kyfb.kyfbdto.firmas.bo.FicheroPdteFirma;
import com.bbva.kyfb.kyfbdto.firmas.bo.FirmaComponente;
import com.bbva.kyfb.kyfbdto.firmas.bo.ObjetoFirmable;
import com.bbva.kyfb.kyfbdto.firmas.bo.UpdateInfoInDto;
import com.bbva.kyfb.kyfbdto.firmas.bo.UsuarioInfo;
import com.bbva.kyfb.kyfbdto.firmas.errores.Errores_kyfb_servicios;
import com.bbva.kyfb.kyfbdto.firmas.fachada.v01.SignedComponent;
import com.bbva.kyfb.kyfbdto.firmas.fachada.v01.SignedComponentsResponse;
import com.bbva.kyfb.kyfbdto.firmas.filtros.FiltroFicheros;
import com.bbva.kyfb.kyfbjpatlbh.dominiotlbh.Ttlsbcor;
import com.bbva.kyfb.kyfbjpatlbh.dominiotlbh.TtlsbcorPK;
import com.bbva.kyfb.kyfbjpatlbh.dominiotlbh.Ttlsbfua;
import com.bbva.kyfb.kyfbjpatlbh.dominiotlbh.Ttlsbont;
import com.bbva.kyfb.kyfbjpatlbh.dominiotlbh.Ttlsbsfo;
import com.bbva.kyfb.kyfbjpatlsb.dominiotlsb.Ttlsbffs;
import com.bbva.kyfb.kyfbofi.converters.ResulSetDtoConverter;
import com.bbva.kyfb.kyfbutils.constantes.ConstantesFO;
import com.bbva.kyfb.kyfbutils.constantes.UtilFO;
import com.bbva.kyfb.kyfbutils.pau.ConstantesPAU;
import com.bbva.kyfb.kyfbutils.pau.FuncionesPAU;
import com.grupobbva.sl.an.pau.fds.OperFDS;
import com.bbva.kytv.dto.kygu.UsuarioEmpresaDTO;

/**
 * The Class ServicioFirmasBoUtil.
 *
 * @author xe20973
 */
@Service("servicioFirmasBoUtil")
public class ServicioFirmasBoUtil {

	/** Variable LOG. */
	private static final I18nLog LOG = I18nLogFactory.getLogI18n(ServicioFirmasBoUtil.class);



	/** The servicio firmas dao. */
	@Autowired
	private IFirmasDao servicioFirmasDao;
	
	/** The servicio firmas bo asistente util */
	@Autowired
	private ServicioFirmasBoAsistenteUtil servicioFirmasBoAsistenteUtil;
	
	/** The servicio firmas bo clients util */
	@Autowired
	private ServicioFirmasBoClientsUtil servicioFirmasBoClientsUtil;


	/**
	 * actualizarPutFirmaComponente Actualiza la bbdd al hacer el put. Las
	 * tablas afectadas son CAB, SFO, FFS y FUA
	 *
	 * @param codClienteCash the cod cliente cash
	 * @param fichero the fichero
	 * @param firmaComponente the firma componente
	 * @param cf the cf
	 * @param codAccion the cod accion
	 * @throws PropiedadNoEncontradaExcepcion the propiedad no encontrada excepcion
	 */
	public void actualizarPutFirmaComponente(final String codClienteCash, final FicheroPdteFirma fichero, final FirmaComponente firmaComponente, final ComponentePutFirma cf , final char xsnFirmado) throws PropiedadNoEncontradaExcepcion {
		// Insertamos en la CAB
		servicioFirmasDao.updateEstadoFichero(UtilFO.getCodNumero(fichero.getsCodEstadoFichero()),codClienteCash, cf.getsTipoOrden().toString(),	cf.getsIdOrdenFirmas());// CAB
		// Insertamos en la SFO
		servicioFirmasDao.updatePesoEstadoFirma(fichero.getsCodEstadoFichero(), fichero.getlPesoActual(),	codClienteCash, cf.getsTipoOrden().toString(), cf.getsIdOrdenFirmas());// SFO
		// Insertamos en la FFS
		final Ttlsbffs ffs = ResulSetDtoConverter.formarFFS(fichero, firmaComponente, cf, xsnFirmado);
		servicioFirmasDao.insertFirmante(ffs);// FFS

	}


	public void insertarFirmanteAuditoria(final String codClienteCash,
			final FicheroPdteFirma fichero,
			final FirmaComponente firmaComponente, final ComponentePutFirma cf,
			final short codAccion) {
		try {
			// Se lee la de la tabla fua para saber que numero
			// de intento llevamos y luego lo guardaremos como COD_IDACCION
			final int intentoAud = servicioFirmasDao.countNumAuditoria(codClienteCash, cf.getsTipoOrden().toString(),cf.getsIdOrdenFirmas(), codAccion);
			// Insertamos en la FUA
			final Ttlsbfua fua = ResulSetDtoConverter.formarFUA(codClienteCash, fichero ,firmaComponente, cf, codAccion, intentoAud);
			servicioFirmasDao.insertAuditoriaFirma(fua);// FUA
		} catch (final Exception e) {
			LOG.error("ServicioFirmasBoImpl.actualizarPutFirmaComponente - Ha ocurrido un error al persistir en la FUA");
		}
	}


	/**
	 * actualizarError Actualizara la lista de errores que se le pasa con el
	 * nuevo error que tambien se le pasara.
	 * @param errors the errors
	 * @param codError the cod error
	 * @param sIdOrdenFirmas the s id orden firmas
	 * @param sTipoOrden the s tipo orden
	 * @return the signed components response
	 */
	public SignedComponentsResponse actualizarError(final SignedComponentsResponse errors, final String codError,
			final String sIdOrdenFirmas, final String sTipoOrden, final String codErrorTx, final String descError,
			final String sObservaciones) {
		final ArrayList<SignedComponent> errores;
		if (errors != null && !CollectionUtils.isEmpty(errors.getSignedComponents())) {
			errores = errors.getSignedComponents();
		} else {
			errores = new ArrayList<SignedComponent>();
		}

		final SignedComponent sc = new SignedComponent();
		sc.setCodError(codError);
		sc.setCodErrorTx(codErrorTx);
		sc.setDescError(descError);
		sc.setsObservaciones(sObservaciones);
		sc.setsIdOrdenFirmas(sIdOrdenFirmas);
		sc.setsTipoOrden(sTipoOrden);
		errores.add(sc);

		final SignedComponentsResponse scr = new SignedComponentsResponse();
		scr.setSignedComponents(errores);
		return scr;
	}

	/**
	 * Creates the filtro from dto.
	 *
	 * @param file the file
	 * @return the filtro ficheros
	 * @throws ExcepcionEjecucionAplicacion the excepcion ejecucion aplicacion
	 */
	public FiltroFicheros createFiltroFromDto(final FicheroInfo file) throws ExcepcionEjecucionAplicacion {
		FiltroFicheros filtro = null;
		try {
			if (file != null) {
				filtro = new FiltroFicheros();
				if (file.getsCodEstado() != null) {
					// TODO: MAPEAR ESTADOS Y CONSTANTES. METODO ESTATICO EN EL UTILS
					filtro.setEstados(new String[file.getsCodEstado().length]);
					for (int i=0;i<file.getsCodEstado().length;i++) {
						filtro.getEstados()[i]=UtilFO.getCodSigla(file.getsCodEstado()[i]);
					}
				}
				if (file.getsDivisa() != null) {
					filtro.setDivisas(file.getsDivisa());
				}
				if (file.getsTipoFecha() != null
						&& !file.getsTipoFecha().equals("")) {
					if (file.getsTipoFecha().equals(UtilFO.FECHA_PROCESO)) {
						if (file.getsFechaDesde() != null) {
							filtro.setFechaProcesoDesde(file.getsFechaDesde());
						}
						if (file.getsFechaHasta() != null) {
							filtro.setFechaProcesoHasta(file.getsFechaHasta());
						}
					} else if (file.getsTipoFecha().equals(UtilFO.FECHA_CREACION)) {
						if (file.getsFechaDesde() != null) {
							filtro.setFechaCreacionDesde(file.getsFechaDesde());
						}
						if (file.getsFechaHasta() != null) {
							filtro.setFechaCreacionHasta(file.getsFechaHasta());
						}
					} else {
						throw new ExcepcionEjecucionAplicacion(
								Errores_kyfb_servicios.FORMATO_INCORRECTO);
					}
				}
				if (file.getsImporteDesde() != null) {
					filtro.setImporteDesde(file.getsImporteDesde());
				}
				if (file.getsImporteHasta() != null) {
					filtro.setImporteHasta(file.getsImporteHasta());
				}
				if (file.getsTipoOrden() != null) {
					filtro.setClaseOrden(file.getsTipoOrden());
				}
				if (file.getsUsuarioOrdenante() != null) {
					filtro.setCodUsuario(file.getsUsuarioOrdenante());
				}
				if (file.getIdOrden() != null) {
					filtro.setIdOrden(file.getIdOrden());
				}
				//if(file.getsValorOrdenacion()!=null)
				filtro.setOrdenarPor(UtilFO.getCampoOrden(file.getsValorOrdenacion(), ConstantesFO.PET_PENDIENTE));
				if(file.getsModoOrdenacion()!=null) {
					filtro.setModoOrdenacion(file.getsModoOrdenacion());
				}
				if(file.getsPaginacionDesde()!=0) {
					filtro.setPaginarDesde(file.getsPaginacionDesde());
				}
				if(file.getsPaginacionNumElementos()!=0) {
					filtro.setNumElementos(file.getsPaginacionNumElementos());
				}
			}
		} catch (final Exception e) {
			throw new ExcepcionEjecucionAplicacion(
					Errores_kyfb_servicios.FORMATO_INCORRECTO, e);
		}
		return filtro;
	}

	/**
	 * Se devuelve el numero aleatorio asociado al par <NumItem, Usuario> disponible en base de datos
	 * En caso de que no existiera, se genera un nuevo numero aleatorio, se inserta en bbdd, y se devuelve
	 * @param numerosAleatorios el hash de numeros aleatorios disponibles
	 * @param fichero la informacion del fichero pendiente de firma
	 * @param info la informacion de entrada al proceso
	 * @param codigo el codigo que sera la key del map (codUsuario)
	 * @return el numero aleatorio
	 * @throws ExcepcionEjecucionAplicacion
	 */
	public String asignarNumeroAleatorio(final Map<String, String> numerosAleatorios, final FicheroPdteFirma fichero,
			final FicheroInfo info, final String codigo) throws ExcepcionEjecucionAplicacion {

		String numAleatorio;
		final String cod = codigo.trim();

		if (numerosAleatorios.containsKey(cod)) {
			// El codigo esta disponible. Tenemos el numero aleatorio
			numAleatorio = numerosAleatorios.get(cod);
		} else {
			// El codigo no esta disponible. Vamos a generarlo
			numAleatorio = Long.toString(FuncionesPAU.getReferenciaNPosiciones(UtilFO.LONGITUD_NUM_ALEATORIO));
			fichero.setsNumeroAleatorio(numAleatorio);
			// Si el codigo de usuario llega vacio, lo seteamos
			info.setsCodUsuario(cod);
			final Ttlsbffs ffs = ResulSetDtoConverter.formarFFS(fichero, info);
			// Lo insertamos en la tabla FFS
			try {
				servicioFirmasDao.insertFFS(ffs);
			} catch (final ExcepcionEjecucionAplicacion ex) {
				// Si se produce algun problema al insertar en la FFS, no vamos a abortar todo el proceso
				// Unicamente se devolvera entonces el numero aleatorio en blanco
				LOG.debug("ServicioFirmasBoUtil.asignarNumeroAleatorio - Ha ocurrido un error al persistir en la FFS",ex);
				numAleatorio = "";
				fichero.setsNumeroAleatorio("");
			}
		}
		return numAleatorio;
	}

	/**
	 * Realiza la comprobacion de si un fichero (NumItem) posee un numero aleatorio.
	 * Si lo posee, se devuelve asignado en la estructura FicheroPdteFirma.
	 * Si no no lo posee, el numero aleatorio se inicializa a cadena vacia
	 * @param fichero lleva la informacion del fichero pendiente de firma (NumItem)
	 * @param fichNumAleatorios map con los numeros aleatorios disponibles para todos los ficheros del usuario
	 * @throws ExcepcionEjecucionAplicacion
	 */
	public void comprobarAsignacionNumeroAleatorio(final FicheroPdteFirma fichero, final Map<String, String> fichNumAleatorios)
			throws ExcepcionEjecucionAplicacion {
		if (fichNumAleatorios.containsKey(Long.toString(fichero.getsNumItem()))) {
			// Si el NumItem esta en el listado, lo devolvemos
			fichero.setsNumeroAleatorio(fichNumAleatorios.get(Long.toString(fichero.getsNumItem())));
		} else {
			// Si el NumIntem no esta en el listado, no lo podemos devolver
			fichero.setsNumeroAleatorio("");
		}
	}

	/**
	 * Realiza la insercion del numero aleatorio para el fichero indicado.
	 * Si falla la insercion, se realiza a traves de update
	 * @param fichero lleva la informacion del fichero
	 * @param info lleva la informacion de entrada al servicio
	 * @throws ExcepcionEjecucionAplicacion
	 */
	public void insertarActualizarNumeroAleatorio(final FicheroPdteFirma fichero, final UpdateInfoInDto info, final String poderFirma) throws ExcepcionEjecucionAplicacion {

		final FicheroInfo ficheroInfo = new FicheroInfo();
		ficheroInfo.setsCodUsuario(info.getsCodUsuario());
		ficheroInfo.setCodCanal(info.getsCanal());
		ficheroInfo.setCodClienteCash(info.getsCanal()+info.getsBancoInt()+info.getsReferencia());
		ficheroInfo.setsBancoProducto(info.getsBancoProducto());
		ficheroInfo.setsCodSubproducto(info.getsCodSubProducto());
		ficheroInfo.setsCodProducto(info.getsProductoServicio());
		ficheroInfo.setStipoFirma(info.getsTipoFirmante());
		fichero.setsPoderFirma(poderFirma);

		final Ttlsbffs ffs = ResulSetDtoConverter.formarFFS(fichero, ficheroInfo);

		try {
			// Lo insertamos en la tabla FFS
			servicioFirmasDao.insertFFS(ffs);
			LOG.info("ServicioFirmasBoUtil.insertarActualizarNumeroAleatorio - Se ha insertado correctamente en la FFS");
		} catch (final JpaSystemException je){
			if((je.getCause() instanceof PersistenceException) && (je.getCause().getCause() instanceof ConstraintViolationException)) {
				// Si se produce algun problema al insertar en la FFS, vamos a hacer update a la FFS
				LOG.info("ServicioFirmasBoUtil.insertarActualizarNumeroAleatorio - Ha ocurrido un error al insertar en la FFS: "+je.getMessage());
				LOG.info("ServicioFirmasBoUtil.insertarActualizarNumeroAleatorio - Se va a hacer UPDATE en la FFS");
				servicioFirmasDao.updateNumAleatorioFFS(ffs);
				LOG.info("ServicioFirmasBoUtil.insertarActualizarNumeroAleatorio - Se ha actualizado correctamente en la FFS");
			}
		} catch (final ExcepcionEjecucionAplicacion ex) {
			// Si se produce algun problema al insertar en la FFS, vamos a hacer update a la FFS
			LOG.info("ServicioFirmasBoUtil.insertarActualizarNumeroAleatorio - Ha ocurrido un error al insertar en la FFS: "+ex.getMessage());
			LOG.info("ServicioFirmasBoUtil.insertarActualizarNumeroAleatorio - Se va a hacer UPDATE en la FFS");
			servicioFirmasDao.updateNumAleatorioFFS(ffs);
			LOG.info("ServicioFirmasBoUtil.insertarActualizarNumeroAleatorio - Se ha actualizado correctamente en la FFS");
		}
	}

	/**
	 * marchaAtras Funcion para volver a dejar las tablas CAB SFO y FFS tal y
	 * como estaban.
	 * @param sfoBck
	 * @param codClienteCash
	 * @param fichero
	 * @param firmaComponente
	 * @param cpf
	 */
	public void marchaAtras(final Ttlsbsfo sfoBck,
			final String codClienteCash, final FicheroPdteFirma fichero,
			final FirmaComponente firmaComponente, final ComponentePutFirma cpf ) {

		try {
			fichero.setlPesoActual(Double.valueOf(sfoBck.getQnuPesofir().toString()));
			fichero.setsCodEstadoFichero(sfoBck.getCodEstadods());
			actualizarPutFirmaComponente(
					codClienteCash, fichero,
					firmaComponente, cpf, UtilFO.XSN_FIRMADO_N);
		} catch (final Exception e) {
			LOG.warn("ServicioFirmasBoUtil.marchaAtras - Ha dado un error al realizar la marcha atras",e);
		}


	}


	/**
	 * @param listaDisclaimer
	 * @param usuario
	 * @param cpf
	 * @return
	 */
	public List<String> comprobarActualizarDisclaimers(final List<String> listaDisclaimer,
			final UsuarioInfo usuario, final ComponentePutFirma cpf ) {
		final List<String> listaDisList = new ArrayList<String>(listaDisclaimer);
		// Se comprueba que no se haya ya insertado y que se deba insertar
		if( !listaDisList.contains(cpf.getsTipoOrden()) &&
				!StringUtils.isEmpty(cpf.getsAceptacionDisclaimer()) &&
				cpf.getsAceptacionDisclaimer().equalsIgnoreCase(ConstantesFO.GRABAR_DISCLAIMER) ) {
			try {
				// Insertamos en la ONT
				final Ttlsbont ont = ResulSetDtoConverter.formarONT( usuario, cpf );
				servicioFirmasDao.insertDisclaimer(ont);// ONT
				// Una vez actualizada la tabla de actualiza la lista para no volver a ejecutarla
				listaDisList.add(cpf.getsTipoOrden());
			}catch(final Exception e){
				LOG.info("ServicioFirmasBoClientsUtil.comprobarActualizarDisclaimers - Ha ocurrido un error al actualizar por el disclaimer. TipoOrden: ".concat(cpf.getsTipoOrden()));
			}

		}
		return listaDisList;
	}

	/**
	 * @param fichero
	 * @param file
	 * @param listAud
	 * @throws PropiedadNoEncontradaExcepcion
	 * @throws IOException
	 */
	public void lanzarAlertasPNM(final FicheroPdteFirma fichero,
			final FicheroInfo file, final List<UsuarioEmpresaDTO> listAud) throws PropiedadNoEncontradaExcepcion, IOException {

		String aux = ConstantesFO.VACIO;

		LOG.info("Se procede a lanzar Alertas PNM");

		final String sEntorno = ArqSpringContext.getPropiedad(ConstantesFO.RAIZ);

		final String[] parametros = new String[25];
		parametros[0] = sEntorno.concat(
				ArqSpringContext.getPropiedad(ConstantesFO.RUTA_PNM_SH))
				.concat(ArqSpringContext.getPropiedad(ConstantesFO.NOMBRE_PNM_SH));
		//parametros[1] = sEntorno != null ? sEntorno : Constantes.CAMPO_VACIO_SH;
		parametros[1] = sEntorno;

		// Datos para el Contexto Rest
		aux = ArqSpringContext.getContextoEscritorio().getPerfil()
				.getBancoFisico();
		parametros[2] = aux != null ? aux.trim() : ConstantesFO.CAMPO_VACIO_SH;
		aux = ArqSpringContext.getContextoEscritorio().getPerfil()
				.getOficinaFisica();
		parametros[3] = aux != null ? aux.trim() : ConstantesFO.CAMPO_VACIO_SH;
		aux = ArqSpringContext.getContextoEscritorio().getPerfil()
				.getIdioma();
		parametros[4] = aux != null ? aux.trim() : ConstantesFO.CAMPO_VACIO_SH;
		aux = ArqSpringContext.getContextoEscritorio().getPerfil()
				.getIdiomaIso();
		parametros[5] = aux != null ? aux.trim() : ConstantesFO.CAMPO_VACIO_SH;
		aux = ArqSpringContext.getContextoEscritorio().getPerfil().getPaisOficina();
		parametros[6] = aux != null ? aux.trim() : ConstantesFO.CAMPO_VACIO_SH;
		aux = ArqSpringContext.getContextoEscritorio().getPuesto()
				.getPuestoLogico();
		parametros[7] = aux != null ? aux.trim() : ConstantesFO.CAMPO_VACIO_SH;
		parametros[8] = ConstantesFO.CAMPO_VACIO_SH;
		aux = ArqSpringContext.getContextoEscritorio().getMedioAcceso();
		parametros[9] = aux != null ? aux.trim() : ConstantesFO.CAMPO_VACIO_SH;
		aux = ArqSpringContext.getContextoEscritorio()
				.getServicioProducto();
		parametros[10] = aux != null ? aux.trim() : ConstantesFO.CAMPO_VACIO_SH;

		// Datos Para Entrada InfoFilteredSigners
		parametros[11] = ConstantesFO.CAMPO_VACIO_SH;
		parametros[12] = ConstantesFO.CAMPO_VACIO_SH;
		parametros[13] = ConstantesFO.CAMPO_VACIO_SH; // Integer.toString(df.getIBncoInt());
		parametros[14] = ConstantesFO.CAMPO_VACIO_SH;
		parametros[15] = ConstantesFO.CAMPO_VACIO_SH; // s_producto
		parametros[16] = ConstantesFO.CAMPO_VACIO_SH; // df.getIProdServ()
		parametros[17] = file.getCodClienteCash().substring(8, 16);
		parametros[18] = ConstantesFO.CAMPO_VACIO_SH; // iServicioLocal
		parametros[19] = ConstantesFO.CAMPO_VACIO_SH; // df.getISubProdu()
		parametros[20] = cargarReferenciasAuditores(file, listAud);
		parametros[21] = ConstantesFO.CAMPO_VACIO_SH; // s_tipo_firma
		if (ConstantesFO.ORDEN_ONLINE_NOMBRE_FICHERO.equals(fichero.getsNombreFichero().trim())) {
			parametros[22] = ArqSpringContext
					.getPropiedad(ConstantesFO.ID_ALERTA_ORDEN);
		} else {
			parametros[22] = ArqSpringContext
					.getPropiedad(ConstantesFO.ID_ALERTA_FICHERO);
		}
		parametros[23] = fichero.getsIdOrdenFirmas();
		parametros[24] = fichero.getsCodTipoOrden();

		LOG.info("Array de parametros: ".concat(StringUtils.join(
				parametros, ConstantesFO.ALMOADILLA)));

		Runtime.getRuntime().exec(parametros);
	}

	/**
	 * @param file
	 * @param listAud
	 * @return
	 */
	private String cargarReferenciasAuditores(final FicheroInfo file,
			final List<UsuarioEmpresaDTO> listAud) {

		final String sReferencia = file.getCodClienteCash().substring(8, 16);
		final StringBuilder sb = new StringBuilder();
		String referencias = ConstantesFO.VACIO;

		// Formamos pares referencia, usuario separado por ;
		for (final UsuarioEmpresaDTO ut : listAud) {
			sb.append(sReferencia.concat(ConstantesFO.COMA).concat(ut.getCodUsuario())
					.concat(ConstantesFO.PUNTO_Y_COMA));
		}
		referencias = sb.toString();
		referencias = referencias.substring(0, referencias.length() - 1);
		return ConstantesFO.COMILLA_SIMPLE.concat(referencias).concat(ConstantesFO.COMILLA_SIMPLE);
	}


	/**
	 * @param fichero
	 * @param file
	 * @param listAud
	 * @throws PropiedadNoEncontradaExcepcion
	 * @throws IOException
	 */
	public void lanzarNotificaciones(final DatosPAU datosPAU) throws PropiedadNoEncontradaExcepcion, IOException {
		// se comprueba que existan registros en la TLWMTER
		if( servicioFirmasDao.countNumNotificacion(datosPAU.getsReferencia(),
				datosPAU.getsCodUsuario(), ConstantesFO.XSN_AVISNOTI) > 0 ) {
			String sEntorno = null;
			sEntorno = ArqSpringContext.getPropiedad(ConstantesFO.RAIZ);
			final String[] parametros = new String[10];
			parametros[0] = sEntorno.concat(
					ArqSpringContext.getPropiedad(ConstantesFO.RUTA_SCRIPT_NOTIFICACION))
					.concat(ArqSpringContext.getPropiedad(ConstantesFO.NOMBRE_SH_NOTIFICACION));
			parametros[1] = sEntorno;
			parametros[2] = datosPAU.getsCanal();
			parametros[3] = datosPAU.getsBancoInt();
			parametros[4] = datosPAU.getsReferencia();
			parametros[5] = datosPAU.getsBancoProducto();
			parametros[6] = datosPAU.getsProductoServicio();
			parametros[7] = datosPAU.getsCodSubProducto();
			parametros[8] = ConstantesFO.PARAMETRO8;
			parametros[9] = ConstantesFO.PARAMETRO9;

			LOG.info("Array de parametros: ".concat(StringUtils.join(
					parametros, ConstantesFO.ALMOADILLA)));

			Runtime.getRuntime().exec(parametros);
			LOG.info("ServicioFirmasBoUtil.lanzarNotificaciones - Se procede a lanzar las notificaciones.");
		}else {
			LOG.info("ServicioFirmasBoUtil.lanzarNotificaciones - No existen datos para poder lanzar las notificaciones.");
		}
	}


	/**
	 * lanzarFDS
	 * 
	 * @param buscarObjFirmable
	 * @param ficheroPdteFirma
	 * @param firmaComponente
	 * @return
	 */
	@Transactional(value="tlbh")
	public boolean lanzarFDS(ObjetoFirmable buscarObjFirmable, FicheroPdteFirma ficheroPdteFirma, FirmaComponente firmaComponente) {
		boolean permitirContinuar = true;
		try {
			// Se comprueba si se debe llamar a fds
			if(buscarObjFirmable.isXsnFdsenv()) {
				// Array de campos vacios
				final ArrayList<String> camposVacios = new ArrayList<String>(Arrays.asList("ENTRY_MODE",
						"SESSIONID", "LOCALE", "AUTH_FACTOR", "MOBILE", "SRC_INSTITUTION_NAME",
						"SRC_INSTITUTION_COUNTRY", "SRC_ACCOUNT_OFFICE", "DST_ACCOUNT",
						"DST_INSTITUTION_NAME", "DST_INSTITUTION_COUNTRY", "DST_ACCOUNT_OFFICE",
						"BENEFICIARY_NAME", "TRANSFER_COMMENT", "AMOUNT_ORIG", "CURRENCY", "ALERT_MOBILE",
						"ALERT_EMAIL", "TRANSFER_TYPE", "SRC_VALIDATED_PHONE", "ALIAS", "PAY_CATEGORY"));
				// Hay que llamar a la COR para sacar la cuenta origen
				Ttlsbcor cor = Ttlsbcor.findTtlsbcor(new TtlsbcorPK(ficheroPdteFirma.getsIdOrdenFirmas(),
														firmaComponente.getDatosPAU().getCodClienteCash(),
														buscarObjFirmable.getsCodObj(), 0));
				// Rellenamos la hashteble para pasarsela a fds
				Hashtable<String, String> paramOpFDS = new Hashtable<String, String>();
				paramOpFDS.put("USERNAME", firmaComponente.getDatosPAU().getsCodUsuario());
				paramOpFDS.put("IP", firmaComponente.getDatosPAU().getsIpCliente());
				paramOpFDS.put("USERAGENT", servicioFirmasBoAsistenteUtil.
						obtenerClaveCabeceraHTTP(ConstantesFO.USER_AGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.7.10) Gecko/20050716 Firefox/1.0.6"));//
				paramOpFDS.put("APPLICATION", ConstantesPAU.APPLICATION);// TODO no tengo claro el valor que hay que poner
				paramOpFDS.put("TYPE", ConstantesPAU.TYPE);
				paramOpFDS.put("SIGNATURE_TYPE", "opkey");// TODO hay que preguntar el tipo de firma
				// Inicializamos todos los datos necesarios para formatear el asunto origen
				final FicheroPdteFirma ficheroPdteFirmaAux = (FicheroPdteFirma) BeanUtils.cloneBean(ficheroPdteFirma);
				ficheroPdteFirmaAux.setsAsunto(cor.getDesCuenorig());
				final FicheroInfo fileAux = new FicheroInfo();
				fileAux.setCodClienteCash(firmaComponente.getDatosPAU().getCodClienteCash());
				fileAux.setsBancoProducto(firmaComponente.getDatosPAU().getsBancoProducto());
				fileAux.setsCodSubproducto(firmaComponente.getDatosPAU().getsCodSubProducto());
				fileAux.setsCodProducto(firmaComponente.getDatosPAU().getsProductoServicio());
				paramOpFDS.put("SRC_ACCOUNT", servicioFirmasBoClientsUtil.transformarAsunto(ficheroPdteFirmaAux, fileAux).replaceAll("^[A-Z]{2}[0-9]{2}.", ""));//
				paramOpFDS.put("TRANSFER_DATE", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()));//
				paramOpFDS.put("TRANSFER_CATEGORY", ConstantesPAU.TRANSFER_CATEGORY);
				paramOpFDS.put("AMOUNT", String.valueOf(ficheroPdteFirma.getdImporte()));
				paramOpFDS.put("BILL_NUMBER", String.valueOf(ficheroPdteFirma.getiNumeroOrdenes()));
				// Se aniaden los campos vacios
				for (String elem : camposVacios) {
					paramOpFDS.put(elem, ConstantesFO.VACIO);
				}
				// Realizamos la llamada a FDS
				OperFDS op = new OperFDS();
				op.validaOperFDS(ConstantesPAU.APLICACION_FDS, ConstantesPAU.OPERACION_FDS,
							ConstantesPAU.CANAL_FDS, ConstantesPAU.SECUENCIA_FDS,
							ArqSpringContext.getPropiedad(UtilFO.USUARIO_BBDD_TLBH),
							ConstantesPAU.INTERFAZ_TP, paramOpFDS);
				// Se comprueba si tenemos que tener en cuenta lo que devuelva la llamada
				if(buscarObjFirmable.isXsnFdsrec()) {
					if(!op.getRetorno().equalsIgnoreCase(ConstantesPAU.OPERACION_CORRECTA_FDS)) {
						permitirContinuar = false;
					}
				}
			}
		}catch(Exception e) {
			LOG.error("ServicioFirmasBoUtil.lanzarFDS - Se ha producido un error al lanzar FDS. ".concat(e.getMessage()));
			if(buscarObjFirmable.isXsnFdsrec()) {
				permitirContinuar = false;
			}
		}
		return permitirContinuar;
	}

}
